/*
 * @Author: your name
 * @Date: 2021-04-07 15:47:47
 * @LastEditTime: 2021-07-23 12:05:14
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \dolphin-data-center-front-end\src\utils\axios-interceptors.js
 */
import Cookie from 'js-cookie'
import { logout } from '@/services/user.js'
import context from '../main.js'
/* 文件流导出方法
封装请求的时候，添加responseType，正常使用即可
例如：
 export async function testPostDownloads(params) {
  return request(testPostDownload, METHOD.GET, params, {
    responseType: 'blob',
  })
}
*/

/**
 * @description: GET 导出文件
 * @param {*} response
 * @return {*}
 */
function getExcelFile(params, url) {
  var param = urlEncode(params)
  let a = document.createElement('a')
  a.href = `${url}?${param}` // 创建下载的链接
  // 下载后文件名
  // a.download = decodeURI(response.headers['content-disposition'])
  document.body.appendChild(a)
  a.click() // 点击下载
  document.body.removeChild(a) // 下载完成移除元素
}
/**
 * @description: POST 导出文件
 * @param {*} params
 * @param {*} url
 * @return {*}
 */
function postExcelFile(params, url) {
  //params是post请求需要的参数，url是请求url地址
  var form = document.createElement('form')
  form.style.display = 'none'
  form.action = url
  form.method = 'post'
  form.target = '_self'
  document.body.appendChild(form)
  // 动态创建input并给value赋值
  for (var key in params) {
    var input = document.createElement('input')
    input.type = 'hidden'
    input.name = key
    input.value = params[key]
    form.appendChild(input)
  }

  form.submit()
  form.remove()
}

/**
 * param 将要转为URL参数字符串的对象
 * key URL参数字符串的前缀
 * encode true/false 是否进行URL编码,默认为true
 *
 * return URL参数字符串
 */
var urlEncode = function(param, key, encode) {
  if (param == null) return ''
  var paramStr = ''
  var t = typeof param
  if (t == 'string' || t == 'number' || t == 'boolean') {
    paramStr +=
      '&' +
      key +
      '=' +
      (encode == null || encode ? encodeURIComponent(param) : param)
  } else {
    for (var i in param) {
      var k =
        key == null
          ? i
          : key + (param instanceof Array ? '[' + i + ']' : '.' + i)
      paramStr += urlEncode(param[i], k, encode)
    }
  }
  return paramStr
}

// 响应拦截
const response = {
  /**
   * 响应数据之前做点什么
   * @param response 响应对象
   * @param options 应用配置 包含: {router, i18n, store, message}
   * @returns {*}
   */
  onFulfilled(response, options) {
    let { responseType, method, url } = response.config
    // blob类型为文件下载对象，不论是什么请求方式，直接返回文件流数据
    if (responseType === 'blob' || responseType === 'arraybuffer') {
      console.log('response', response)
      let { params, url } = response.config
      if (method == 'post') {
        postExcelFile(params, url)
      } else {
        getExcelFile(params, url)
      }
    }
    return response
  },
  /**
   * 响应出错时执行
   * @param error 错误对象
   * @param options 应用配置 包含: {router, i18n, store, message}
   * @returns {Promise<never>}
   */
  onRejected(error, options) {
    const { message } = options
    const { response } = error
    console.log('error, options', error, options)
    if (response?.status === 200) {
      message.error('无此权限')
    }
    return Promise.reject(error)
  },
}
// 401拦截
const resp401 = {
  /**
   * 响应数据之前做点什么
   * @param response 响应对象
   * @param options 应用配置 包含: {router, i18n, store, message}
   * @returns {*}
   */
  onFulfilled(response, options) {
    const { message } = options
    if (response?.code === 401) {
      message.error('无此权限')
    }
    return response
  },
  /**
   * 响应出错时执行
   * @param error 错误对象
   * @param options 应用配置 包含: {router, i18n, store, message}
   * @returns {Promise<never>}
   */
  onRejected(error, options) {
    const { message } = options
    const { response } = error
    if (response?.status === 401) {
      message.error('无此权限')
    }
    return Promise.reject(error)
  },
}

const resp403 = {
  onFulfilled(response, options) {
    const { message } = options
    if (response?.code === 403) {
      message.error('请求被拒绝')
    }
    return response
  },
  onRejected(error, options) {
    const { message } = options
    const { response } = error
    // console.log('response', response)
    if (response?.status === 403) {
      message.error('请求被拒绝')
    }
    return Promise.reject(error)
  },
}

const resp999 = {
  onFulfilled(response, options) {
    const { message } = options
    const { data } = response
    if (data.code === 999) {
      logout()
      context.$router.push('/login')
    }
    return response
  },
  onRejected(error, options) {
    const { message } = options
    const { data } = error
    if (data.code === 999) {
      logout()
      context.$router.push('/login')
    }
    return Promise.reject(error)
  },
}

const reqCommon = {
  /**
   * 发送请求之前做些什么
   * @param config axios config
   * @param options 应用配置 包含: {router, i18n, store, message}
   * @returns {*}
   */
  onFulfilled(config, options) {
    // console.log(config)
    const { message } = options
    const { url, xsrfCookieName, responseType, headers } = config
    let localToken = localStorage.getItem('token') || ' '
    let token = localToken.substring(1, localToken.length - 1)
    let isLogin = config.url.endsWith('/login')

    // console.log('config', config, isLogin, token);
    if (responseType == 'arraybuffer' || responseType == 'blob') {
      headers['content-type'] = 'application/x-www-form-urlencoded'
    } else {
      headers['content-type'] = 'application/json'
    }
    if (!isLogin) {
      headers.token = ''
    }
    headers.token = token
    if (
      url.indexOf('login') === -1 &&
      xsrfCookieName &&
      !Cookie.get(xsrfCookieName)
    ) {
      return message.warning('认证 token 已过期，请重新登录')
    }
    return config
  },
  /**
   * 请求出错时做点什么
   * @param error 错误对象
   * @param options 应用配置 包含: {router, i18n, store, message}
   * @returns {Promise<never>}
   */
  onRejected(error, options) {
    const { message } = options
    message.error(error.message)
    return Promise.reject(error)
  },
}

export default {
  request: [reqCommon], // 请求拦截
  response: [response, resp401, resp403, resp999], // 响应拦截
}
